home *** CD-ROM | disk | FTP | other *** search
- UNIT U123; {Soure PC MAG. DECEMBER 13 1988... and others}
- { YES ! I did it in TP seven years Ago !!!}
-
- INTERFACE
-
- {
- This routines ARE simple to use as 123.. :-)
- 1) Open the file
- 2) Add what you want.. where you want
- 3) Close the File
- }
-
- PROCEDURE Open123(n:string);
- PROCEDURE Close123;
- PROCEDURE ColW123(c:integer; a:byte);
- PROCEDURE Add123Int(c,f:integer; v:integer);
- PROCEDURE Add123Rea(c,f:integer; v:double);
- PROCEDURE Add123TXC(c,f:integer; v:string);
- PROCEDURE Add123TXL(c,f:integer; v:string);
- PROCEDURE Add123TXR(c,f:integer; v:string);
- PROCEDURE Add123FML(c,f:integer; s:string);
-
- {
- Open123(n:string);
- n = File Name WITHOUT EXTENSION it ALways add WK1
- It didn't check for a valid File Name or Existing, is
- YOUR responsability to do that
-
-
- Close123;
- Close the Open File .. Always DO THIS !
-
- In the rest of PROCEDURES c=Column and f=Row
- c and F begins with 0 (cero)
- if you want to Add in cell A1, use c=0 f=0
- if you want to Add in cell B2, use c=1 f=1
- etc.
-
-
- Add123Int(c,f:integer; v:integer);
- Add a Integer value (v) in Col=c Row=f
-
- Add123Rea(c,f:integer; v:double);
- Add a Double value (v) in Col=c Row=f
-
- Add123TXC(c,f:integer; v:string);
- Add a Label (v) in Col=C Row=f
- - Label CENTER -
-
- Add123TXR(c,f:integer; v:string);
- Add a Label (v) in Col=C Row=f
- - Label at RIGHT -
-
- Add123TXL(c,f:integer; v:string);
- Add a Label (v) in Col=C Row=f
- - Label at LEFT -
-
- ColW123(c:integer; a:byte);
- Change width of Col=c to size=a
-
- Add123FML(c,f:integer; s:string);
- Add Formula (s) at Col=c Row=f
-
- Examples:
- Add123FML(0,0,'A5+B2+A3*C5');
- Add123FML(0,1,'@Sum(B1..B8)');
-
- ==========================================
- THE ONLY VALID @ function is SUM !!!!
- Sorry :-(
- ==========================================
-
- }
-
-
- { The rest of Comments are in SPANISH ... Sorry again }
-
-
- IMPLEMENTATION
- CONST
- C00 = $00;
- CFF = $FF;
-
- VAR
- ALotus : File;
-
- PROCEDURE Open123(n:string);
-
- Type
- Abre = record
- Cod : integer;
- Lon : integer;
- Vlr : integer;
- end;
-
- Var
- Formato : array[1..6] of byte;
- Registro : Abre absolute Formato;
-
-
- Begin
- Assign(ALotus,n+'.WK1');
- Rewrite(ALotus,1);
- with Registro do
- begin
- Cod:=0;
- Lon:=2;
- Vlr:=1030;
- end;
- BlockWrite(ALotus,Formato[1],6);
- End;
-
- PROCEDURE Close123;
-
- Type
- Cierra = record
- Cod : integer;
- Lon : integer;
- end;
-
- Var
- Formato : array[1..4] of byte;
- Registro : Cierra absolute Formato;
-
-
- Begin
- with Registro do
- begin
- Cod:=1;
- Lon:=0;
- end;
- BlockWrite(ALotus,Formato[1],4);
- Close(ALotus);
- End;
-
- PROCEDURE ColW123(c:integer; a:byte);
-
- Type
- Ancho = record
- Cod : integer;
- Lon : integer;
- Col : integer;
- Anc : byte;
- end;
-
- Var
- Formato : array[1..7] of byte;
- Registro : Ancho absolute Formato;
-
-
- Begin
- with Registro do
- begin
- Cod:=8;
- Lon:=3;
- Col:=c;
- Anc:=a;
- end;
- BlockWrite(ALotus,Formato[1],7);
- End;
-
-
- PROCEDURE Add123Int(c,f,v:integer);
-
- Type
- Entero = record
- Cod : integer;
- Lon : integer;
- Frm : byte;
- Col : integer;
- Fil : integer;
- Vlr : integer;
- end;
-
- Var
- Formato : array[1..11] of byte;
- Registro : Entero absolute Formato;
-
- Begin
- with Registro do
- begin
- Cod:=13;
- Lon:=7;
- Frm:=255;
- Fil:=f;
- Col:=c;
- Vlr:=v;
- end;
-
- Blockwrite(ALotus,Formato[1],11);
- End;
-
- PROCEDURE Add123Rea(c,f:integer; v:double);
- Type
- Entero = record
- Cod : integer;
- Lon : integer;
- Frm : byte;
- Col : integer;
- Fil : integer;
- Vlr : double;
- end;
- Var
- Formato : array[1..17] of byte;
- Registro : Entero absolute Formato;
- Begin
- with Registro do
- begin
- Cod:=14;
- Lon:=13;
- Frm:=2 or 128;
- Fil:=f;
- Col:=c;
- Vlr:=v;
- end;
-
- Blockwrite(ALotus,Formato[1],17);
- End;
-
-
- PROCEDURE GrabaTXT(c,f:integer; v:string; t:char);
- Type
- Entero = record
- Cod : integer;
- Lon : integer;
- Frm : byte;
- Col : integer;
- Fil : integer;
- Vlr : array[1..100] of char;
- end;
- Var
- Formato : array[1..109] of byte;
- Registro : Entero absolute Formato;
- i : word;
- Begin
- with Registro do
- begin
- Cod:=15;
- Lon:=length(v)+7;
- Frm:=255;
- Fil:=f;
- Col:=c;
- Vlr[1]:=t;
- for i:=1 to Length(v) do Vlr[i+1]:=v[i];
- Vlr[i+2]:=chr(0);
- end;
- Blockwrite(ALotus,Formato[1],length(v)+11);
- End;
-
- PROCEDURE Add123TXL(c,f:integer; v:string);
- begin
- GrabaTXT(c,f,v,'''');
- end;
- PROCEDURE Add123TXC(c,f:integer; v:string);
- begin
- GrabaTXT(c,f,v,'^');
- end;
- PROCEDURE Add123TXR(c,f:integer; v:string);
- begin
- GrabaTXT(c,f,v,'"');
- end;
-
-
-
-
-
-
- PROCEDURE Add123FML(c,f:integer; s:string);
-
- Type
- Formula = record
- Cod : integer; {codigo}
- Lon : integer; {longitud}
- Frm : byte; {formato}
- Col : integer; {columna}
- Fil : integer; {fila}
- Res : Double; {resultado de formula}
- Tma : integer; {tamanio de formula en bytes}
- Fml : array[1..2048] of byte; {formula}
- end;
- symbol = (cel,num,arr,mas,men,por,dvs,pot,pa1,pa2);
- consym = set of symbol;
-
- Var
- Formato : array[1..2067] of byte;
- Registro : Formula absolute Formato;
- fabs : boolean; {flag que indica si ffml es absoluta}
- v, {v = string 's' sin blancos}
- nro : string; {nro = numero de ffml}
- cfml, {cfml = valor de columna en formula}
- ffml : word; {ffml = " " fila " " }
- nfml, {nfml = " " constante " " }
- i, {i = indice de 'v' (formula) }
- ii, {ii = " " 's' " }
- index, {index= " " Fml}
- j,ret, {usados para convertir a numeros}
- len, {len = longitud de 'v'}
- lens : integer; {lens = " " 's'}
- sym : symbol; {sym = ultimo simbolo leido}
- symsig, {usados para analizar formula para }
- syminifac : consym; {grabarla con notacion posfija }
- z : byte; {indice para inicializar array}
-
-
- Procedure CalculaDir(var Reg : Formula);
-
- var
- veces : integer;
-
- (* Primero, se decide si cfml es absoluta o relativa. Si es absoluta
- calcula el valor real. Si es relativa primero chequea si cfml<col.
- Si cfml<col le resta cfml a 49152 (C000); este numero es usado por
- Lotus para calcular la direccion de una celda a la izquierda de
- donde esta parado. Si col<=cfml le suma cfml a 32768 para encender
- el MSB que indica que es relativa (la C tambien lo prende).
-
- Segundo, se procede de la misma manera con ffml para determinar si
- es absoluta o relativa, y despues se calcula la direccion en base
- a eso y a la relacion de ffml con fil.
- *)
-
- begin
- with Reg do
- begin
- if v[i]='$' then {calcula la columna (cfml)}
- begin
- inc(i);
- cfml:=ord(v[i])-ord('A');
- inc(i);
- while (v[i] in ['A'..'Z']) and (len>=i) do
- begin
- cfml:=(cfml+1)*26+ord(v[i])-ord('A');
- inc(i);
- end;
- end
- else
- begin
- if (ord(v[i])-ord('A') < col) then
- begin
- cfml:=49152-col+(ord(v[i])-ord('A'));
- inc(i);
- veces:=1;
- while (v[i] in ['A'..'Z']) and (len>=i) do
- begin
- cfml:=49152-col+(26*veces)+(ord(v[i])-ord('A'));
- cfml:=cfml+((ord(v[i-1])-ord('A'))*26);
- inc(i);
- inc(veces);
- end;
- end
- else
- begin
- cfml:=ord(v[i])-ord('A');
- inc(i);
- while (v[i] in ['A'..'Z']) and (len>=i) do
- begin
- cfml:=(cfml+1)*26+ord(v[i])-ord('A');
- inc(i);
- end;
- cfml:=cfml+32768-col;
- end;
- end;
-
- Fml[index]:=Lo(cfml); {graba cfml}
- inc(index); {que posee }
- Fml[index]:=Hi(cfml); {dos bytes }
- inc(index);
-
- if v[i]='$' then {calcula la fila (ffml)}
- begin
- inc(i);
- fabs:=true;
- end
- else
- fabs:=false;
- j:=i;
- while (v[i] in ['0'..'9']) and (len>=i) do
- begin
- inc(i);
- end;
- nro:=copy(v,j,i-j);
- val(nro,ffml,ret);
-
- if fabs then {siempre se resta 1 por estar en base 0}
- begin
- if ffml>0 then ffml:=ffml-1;
- end
- else
- begin
- if fil<ffml then
- begin
- ffml:=32768+abs(ffml-fil)-1;
- end
- else
- begin
- ffml:=49152-abs(ffml-fil)-1;
- end;
- end;
-
- Fml[index]:=Lo(ffml); {graba ffml}
- inc(index); {que posee }
- Fml[index]:=Hi(ffml); {dos bytes }
- inc(index);
- end;
- end;
-
- Procedure CalculaNum(var Reg : Formula);
-
- var
- VDoble : array[1..8] of byte;
- dfml : Double absolute VDoble;
- d : real;
- esreal : boolean;
- k : byte;
- numero : longint;
- codigo : integer;
-
- begin
- with Reg do
- begin
- esreal:=false;
- j:=i;
- while (v[i] in ['0'..'9','.']) and (len>=i) do
- begin
- if v[i]='.' then esreal:=true;
- inc(i);
- end;
- nro:=copy(v,j,i-j);
- {R-}
- val(nro,numero,codigo);
- {R+}
- if (codigo=0) and (numero>=-32768) and (numero<=32767) then
- esreal:=false
- else
- esreal:=true;
-
- if esreal then
- begin
- val(nro,d,ret); {convierte en real doble}
- dfml:=d;
- {ConvRD(d,dfml);}
-
- Fml[index]:=0; {0 = indica que sigue una constante}
- inc(index); { real doble precision (8 bytes)}
- for k:=1 to 8 do
- begin
- Fml[index]:=VDoble[k]; {graba dfml}
- inc(index); {son ocho bytes}
- end;
- end
- else
- begin
- val(nro,nfml,ret); {convierte en entero}
-
- Fml[index]:=5; {5 = indica que sigue una constante }
- inc(index); { entera con signo (2 bytes) }
- Fml[index]:=Lo(nfml); {graba nfml}
- inc(index); {son dos bytes}
- Fml[index]:=Hi(nfml);
- inc(index);
- end;
- dec(i);
- end;
- end;
-
- Procedure CalculaRan(var Reg : Formula);
-
- begin
- with Reg do
- begin
- Fml[index]:=2; {2 = codigo de rango; le sigue 8 bytes}
- inc(index); { que son (col1fil1..col2fil2) }
-
- CalculaDir(Reg); {calcula col1fil1}
- i:=i+2; {salta los 2 .. }
- CalculaDir(Reg); {calcula col2fil2}
- end;
- end;
-
- Procedure CalculaArr(var Reg : Formula);
-
- {** SOLO CODIFICA @TRUE,@FALSE,@SUM(COL1FIL1..COL2FIIL2) **}
-
- var
- func,dir : string; {func = string del @}
- {dir = del rango}
- N_arg,nc : byte; {N_arg = cantidad de argumentos}
- {nc = numero de codigo (T,F,S)}
-
- begin
- with Reg do
- begin
- inc(i);
- case v[i] of
- 'F' : nc:=51;
- 'T' : nc:=52;
- 'S' : nc:=80;
- end;
-
- while (v[i] in ['A'..'Z']) and (len>=i) do inc(i);
- inc(i);
- if nc=80 then
- begin
- CalculaRan(Reg); {calcula el rango (col1fil1..col2fil2}
- N_arg:=1; {hay un solo argumento}
- end;
-
- Fml[index]:=nc;
- inc(index);
- if nc=80 then
- begin
- Fml[index]:=N_arg; {graba numero de argumentos}
- inc(index);
- end;
- end;
- end;
-
- Procedure TraerChar;
-
- begin
- inc(i); {carga el simbolo para }
- if len>=i then {la recursividad }
- begin
- case v[i] of
- 'A'..'Z','$' : sym:=cel;
- '0'..'9','.' : sym:=num;
- '@' : sym:=arr;
- '+' : sym:=mas;
- '-' : sym:=men;
- '*' : sym:=por;
- '/' : sym:=dvs;
- '^' : sym:=pot;
- '(' : sym:=pa1;
- ')' : sym:=pa2;
- end;
- end;
- end;
-
-
- Procedure Expresion(symsig : consym; var Reg : Formula);
- var
- opsuma:symbol;
-
- Procedure Termino(symsig : consym; var Reg : Formula);
- var
- opmul:symbol;
-
- Procedure Factor(symsig : consym; var Reg : Formula);
- var
- opexp:symbol;
-
- Procedure Exponente(symsig : consym; var Reg : Formula);
-
- begin{Exponente}
- while (sym in syminifac) and (len>=i) do
- begin
- case sym of
- num : begin
- CalculaNum(Registro);
- TraerChar;
- end;
- cel : begin
- Reg.Fml[index]:=1;
- inc(index);
- CalculaDir(Registro);
- dec(i);
- TraerChar;
- end;
- arr : begin
- CalculaArr(Registro);
- TraerChar;
- end;
- else
- begin
- if sym=pa1 then
- begin
- TraerChar;
- Expresion([pa2]+symsig,Registro);
- if sym=pa2 then
- begin
- Reg.Fml[index]:=4; {4 = simbolo '(' }
- inc(index);
- TraerChar;
- end;
- end;
- end;
- end;
- end;
- end;{Exponente}
-
- begin{Factor}
- Exponente(symsig+[pot],Registro);
- while (sym=pot) and (len>=i) do
- begin
- opexp:=sym;
- TraerChar;
- Exponente(symsig+[pot],Registro);
- if opexp=pot then
- begin
- Reg.Fml[index]:=13; {13 = simbolo '^' }
- inc(index);
- end;
- end;
- end;{Factor}
-
- begin{Termino}
- Factor(symsig+[por,dvs],Registro);
- while (sym in [por,dvs]) and (len>=i) do
- begin
- opmul:=sym;
- TraerChar;
- Factor(symsig+[por,dvs],Registro);
- if (opmul=por) or (opmul=dvs) then
- begin
- if opmul=por then Reg.Fml[index]:=11 {11 = simbolo '*' }
- else
- Reg.Fml[index]:=12; {12 = simbolo '/' }
- inc(index);
- end;
- end;
- end;{Termino}
-
- begin{Expresion}
-
- (* Este es el primero de cuatro procedimientos recursivos (Expresion,
- Termino, Factor y Exponente) que se usan para transformar la formula
- en una expresion en notacion posfija, tal como se debe grabar. La
- tecnica consiste en retrasar la transmision del operador aritmetico.
- Ejemplo: a+(b*c)^d ==> abc*(d^+ .
-
- Expresion analiza si es suma o resta. Luego llama a Termino. Al
- volver trae el proximo dato y llama otra vez a Termino. Al volver
- genera el codigo de suma o resta si hubo.
-
- Termino llama a Factor. Al volver trae el proximo dato y llama otra
- vez a Factor. Al volver genera el codigo de multiplicacion o division
- si hubo.
-
- Factor llama a Exponente. Al volver trae el proximo dato y llama
- otra vez a Exponente. Cuando vuele genera el codigo de exponenciacion
- si hubo.
-
- Exponente analiza si el valor es un numero, una celda, un arroba o
- un parentesis. Si es un parentesis, vuelve a llamar a Expresion para
- calcular el contenido este; sino genera el codigo correspondiente.
-
- *)
-
- if sym in [mas,men] then
- begin
- opsuma:=sym;
- TraerChar;
- Termino(symsig+[mas,men],Registro);
- if opsuma=men then
- begin
- Reg.Fml[index]:=8; {8 = simbolo '-' unario}
- inc(index);
- end;
- end
- else
- Termino(symsig+[mas,men],Registro);
- while (sym in [mas,men]) and (len>=i) do
- begin
- opsuma:=sym;
- TraerChar;
- Termino(symsig+[mas,men],Registro);
- if (opsuma=mas) or (opsuma=men) then
- begin
- if opsuma=mas then Reg.Fml[index]:=9 { 9 = simbolo '+' }
- else
- Reg.Fml[index]:=10; {10 = simbolo '-' }
- inc(index);
- end;
- end;
- end;{Expresion}
-
-
- Begin
- with Registro do
- begin
- Cod:=16; {16= formula}
- Col:=c;
- Fil:=f;
-
- Frm:=0; {Comienzo con 0}
- (*
- if p=true then Frm:=Frm+128; {Si se protege se prende el MSB}
-
- ch:=UpCase(ch); {Veo que formato se quiere y prendo }
- {los bits respectivos }
- case ch of
- 'F' : Frm:=Frm+ 0; {'F' ==> decimales fijos }
- 'S' : Frm:=Frm+ 16; {'S' ==> notacion cientifica}
- 'C' : Frm:=Frm+ 32; {'C' ==> moneda corriente }
- 'P' : Frm:=Frm+ 48; {'P' ==> porcentaje }
- 'M' : Frm:=Frm+ 64; {',' ==> miles con comas }
- 'O' : Frm:=Frm+112; {'O' ==> otros }
- end;
-
- Frm:=Frm+d; {Si ch<>'O' ==> d= cant. de decimales}
- {Si ch= 'O' ==> d= 1 --> general }
- { 2 --> DD/MMM/AA }
- { 3 --> DD/MMM }
- { 4 --> MM/AA }
- { 5 --> texto }
- { 6 --> hidden }
- { 7 --> date; HH-MM-SS}
- { 8 --> date; HH-MM }
- { 9 --> date; int'l 1 }
- { 10 --> date; int'l 2 }
- { 11 --> time; int'l 1 }
- { 12 --> time; int'l 2 }
- { 13-14 --> no utilizado}
- { 15 --> default }
-
- *)
- Res:=C00;
- { for z:=1 to 8 do Res[z]:=C00;} {se modifica automaticamente cuando se recalcula y regraba}
-
- lens:=length(s); {convierto todo a mayusculas}
- for ii:=1 to lens do s[ii]:=UpCase(s[ii]);
- i:=1;
- v:='';
- for ii:=1 to lens do {paso el string 's' al string 'v' }
- begin {eliminando los espacios en blanco}
- if s[ii]<>' ' then
- begin
- v:=v+s[ii];
- inc(i);
- end;
- end;
-
- len:=i-1;
- i:=0;
- index:=1;
-
- syminifac:=[cel,num,arr,pa1];
- symsig:=syminifac;
-
- TraerChar; {toma el primer caracter de formula}
- Expresion(symsig,Registro); {analiza y graba toda la formula}
-
- Fml[index]:=3; {3 = fin de formula}
- Tma:=index; {tamanio de Fml}
- Lon:=15+Tma; {longitud de dato}
- BlockWrite(ALotus,Formato[1],19+index);
- end;
- End;
-
-
- END.